package com.iwhalecloud.bss.kite.cucc.service.scene.query;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.SeqUtils;
import com.iwhalecloud.bss.kite.common.validate.annotation.KiteNotBlank;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.dto.KiteInstRelDTO;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInstFunc;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.scene.service.OperateSceneInstService;
import com.iwhalecloud.bss.kite.service.scene.AbstractInstService;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.iwhalecloud.bss.kite.service.util.CopyToDtoUtil;
import com.ztesoft.bss.common.util.SpringUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

@Service("querySceneFuncProdInstService")
public class QuerySceneFuncProdInstService extends AbstractInstService implements IQuerySceneFuncProdInstService {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;

    @Autowired
    private IQuerySceneFuncProdInstService querySceneFuncProdInstService;

    @Autowired
    private IQuerySceneAccessProdInstService querySceneProdInstService;

    @Autowired
    private OperateSceneInstService operateSceneInstService;

    /***
     * 根据功能产品id获取接入产品实例的功能产品实例
     *
     * @param sceneInstId
     * @param accessProdInstId 接入产品实例id
     * @param prodId 功能产品id
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    @Validated
    public DataResult<List<ProdInstDTO>> listProdInstFuncsByProdId(@KiteNotBlank String sceneInstId,
        @KiteNotBlank String accessProdInstId, @KiteNotBlank String prodId, @KiteNotBlank String custId) {
        List<KiteProdInstFunc> kiteProdInstFuncList = querySceneInstService.listProdInstFuncsByProdId(custId,
            accessProdInstId, prodId);
        List<ProdInstDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteProdInstFuncList)) {
            dtoList = CopyToDtoUtil.transProdInstDtoListForFunc(kiteProdInstFuncList);
            // TODO 待确认 装箱
        }
        // else {
        // dtoList = queryFuncProdInstBO.getFuncProdInstByAccessProdInstId(accessProdInstId, custId);
        // checkAndPutProdInstFuncList(dtoList, queryFuncProdInstBO);
        // }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /***
     * 查询有效接入产品已经订购的功能产品列表
     *
     * @param sceneInstId
     * @param accessProdInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    @Validated
    public DataResult<List<ProdInstDTO>> listFuncProdInstByProdInstId(@KiteNotBlank String sceneInstId,
        @KiteNotBlank String accessProdInstId, @KiteNotBlank String custId) {
        List<KiteProdInstFunc> kiteProdInstFuncList = querySceneInstService.listProdInstFuncs(custId, accessProdInstId);
        kiteProdInstFuncList.removeIf(kiteProdInstFunc -> Objects.equals(kiteProdInstFunc.getActionType(), ActionType.D));
        List<ProdInstDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteProdInstFuncList)) {
            dtoList = CopyToDtoUtil.transProdInstDtoListForFunc(kiteProdInstFuncList);
        }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /***
     * 查询接入产品已经订购的功能产品列表
     *
     * @param sceneInstId
     * @param accessProdInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    @Validated
    public DataResult<List<ProdInstDTO>> listInUseFuncProdInstByProdInstId(@KiteNotBlank String sceneInstId,
        @KiteNotBlank String accessProdInstId, @KiteNotBlank String custId) {
        List<KiteProdInstFunc> kiteProdInstFuncList = querySceneInstService.listProdInstFuncs(custId, accessProdInstId);
        if (!CollectionUtils.isEmpty(kiteProdInstFuncList)) {
            Iterator<KiteProdInstFunc> itKiteProdInstFunc = kiteProdInstFuncList.iterator();
            while (itKiteProdInstFunc.hasNext()) {
                if (KiteStringUtils.equals(itKiteProdInstFunc.next().getActionType().toString(),
                    ActionType.D.toString())) {
                    itKiteProdInstFunc.remove();
                }
            }
        }

        List<ProdInstDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteProdInstFuncList)) {
            dtoList = CopyToDtoUtil.transProdInstDtoListForFunc(kiteProdInstFuncList);
            // TODO 待确认 装箱
        }
        // else {
        // dtoList = queryFuncProdInstBO.getFuncProdInstByAccessProdInstId(accessProdInstId, custId);
        // checkAndPutProdInstFuncList(dtoList, queryFuncProdInstBO);
        // }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /***
     * 查询功能产品实例属性
     *
     * @param sceneInstId
     * @param prodInstId 功能产品实例标识
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    public DataResult<List<InstAttrDTO>> listFuncProdInstAttrByProdInstId(String sceneInstId, String prodInstId,
        String custId) {
        List<KiteAttr> kiteAttrList = querySceneInstService.listProdInstFuncAttrs(custId, prodInstId);
        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }
        // else {
        // dtoList = queryFuncProdInstBO.listProdInstAttrs(prodInstId, custId);
        // checkAndPutAttr(dtoList, sceneInstId, prodInstId);
        // }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /**
     * Description: <br>
     * 获取功能产品实例属性
     *
     * @taskId <br>
     * @param sceneInstId
     * @param custId
     * @param prodInstId
     * @param showType
     * @return <br>
     */
    @Override
    public DataResult<List<InstAttrDTO>> getProdInstFuncAttrs(String sceneInstId, String custId, String prodInstId,
        String showType) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInstFunc inst = querySceneInstService.getProdInstFunc(custId, prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();

        kiteAttrList = kiteAttrList.stream()
            .filter(kiteAttr -> KiteStringUtils.equals(showType, kiteAttr.getShowType()) || KiteStringUtils.isEmpty(showType))
            .collect(Collectors.toList());

        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, sceneInst);
        kiteAttrList = operateInstAttrService.sortProdAttr(kiteAttrList);

        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }

        return ErrorConsts.SUCCESS.getResult(dtoList);
    }


    /**
     * Description: <br>
     * 获取功能产品实例属性
     *
     * @taskId <br>
     * @param sceneInstId
     * @param custId
     * @param prodInstId
     * @param showType
     * @return <br>
     */
    @Override
    public DataResult<List<InstAttrDTO>> listProdInstFuncAttrs(String sceneInstId, String custId, String prodInstId, String isEdit) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInstFunc inst = querySceneInstService.getProdInstFunc(custId, prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();
        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, sceneInst);
        kiteAttrList = this.listKiteAttr(kiteAttrList, new String[] {"M", "D"
        });
      //  kiteAttrList = operateInstAttrService.sortPordInstFuncAttrs(kiteAttrList);
        kiteAttrList = operateInstAttrService.sortProdInstFuncAttrs(kiteAttrList);

        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            this.saveBeforeEditAttr(isEdit, sceneInstId, prodInstId, kiteAttrList);
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }
        dtoList.removeIf(attrDto -> KiteStringUtils.equals(attrDto.getShowType(), "E"));

        // 互联网大带宽端口编号序列处理
        if(KiteStringUtils.isNotEmpty(inst.getSpecId()) && "300000204".equals(inst.getSpecId())){
            List<KiteProdInstFunc>  prodFuncInstList = querySceneInstService.listProdInstFuncs(custId, inst.getAccProdInstId());
            this.dealbigBangWidthPort( prodFuncInstList, dtoList,sceneInstId, inst);
        }
        // 处理物联网通用定制连接通信计划-启用固定ip（若为默认共享VPN的方式，默认未“否”且置灰）
        if(KiteStringUtils.isNotEmpty(inst.getSpecId()) && "300000151".equals(inst.getSpecId())){
            List<KiteProdInstFunc>  prodInstFuncs = querySceneInstService.listProdInstFuncs(custId, inst.getAccProdInstId());
             this.dealCommonPlanAttr(prodInstFuncs,kiteAttrList,sceneInstId, inst);
        }


        return ErrorConsts.SUCCESS.getResult(dtoList);
    }



    /**
     * Description: <br>
     * 获取功能产品实例属性
     *
     * @taskId <br>
     * @param sceneInstId
     * @param custId
     * @param prodInstId
     * @param showType
     * @return <br>
     */
    @Override
    public DataResult<List<InstAttrDTO>> listAllProdInstFuncAttrs(String sceneInstId, String custId, String prodInstId) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInstFunc inst = querySceneInstService.getProdInstFunc(custId, prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();
        kiteAttrList = this.listKiteAttr(kiteAttrList, new String[] {
            "M", "D", "H"
        });
        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, sceneInst);
      //  kiteAttrList = operateInstAttrService.sortPordInstFuncAttrs(kiteAttrList);
        kiteAttrList = operateInstAttrService.sortProdInstFuncAttrs(kiteAttrList);

        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    @Override
    public DataResult<List<ProdInstDTO>> listFuncProdInstsFromOfferInst(String offerInstId, String custId) {
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custId, offerInstId);
        if (offerInst.getActionType() == ActionType.D) {
            return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
        }
        List<KiteProdInstFunc> kiteProdInstFuncs = querySceneInstService.listInstRelsByAInst(custId, offerInst.getInstType(), offerInstId, InstType.PROD_INST_FUNC)
            .stream()
            .filter(t -> t.getActionType() != ActionType.D)
            .filter(t -> t.getRelType() == RelType.OFFER_PROD_REL_TYPE_1000)
            .map(KiteInstRelDTO::getzInstId)
            .map(t -> querySceneInstService.getProdInstFunc(custId, t))
            .filter(t -> t.getActionType() != ActionType.D)
            .collect(Collectors.toList());
        return ErrorConsts.SUCCESS.getResult(CopyToDtoUtil.transProdInstDtoListForFunc(kiteProdInstFuncs));
    }

    @Override
    public DataResult<List<ProdInstDTO>> listFuncProdInstsFromBaseOfferInst(String prodInstId, String custId) {
        KiteProdInst prodInst = querySceneInstService.getProdInst(custId, prodInstId);
        if (prodInst.getActionType() == ActionType.D) {
            return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
        }
        List<KiteProdInstFunc> kiteProdInstFuncs = querySceneInstService.listInstRelsByAInst(custId, prodInst.getInstType(), prodInstId, InstType.PROD_INST_FUNC)
            .stream()
            .filter(t -> t.getActionType() != ActionType.D)
            .filter(t -> t.getRelType() == RelType.OFFER_PROD_REL_TYPE_1000)
            .map(KiteInstRelDTO::getzInstId)
            .map(t -> querySceneInstService.getProdInstFunc(custId, t))
            .filter(t -> t.getActionType() != ActionType.D)
            .collect(Collectors.toList());
        return ErrorConsts.SUCCESS.getResult(CopyToDtoUtil.transProdInstDtoListForFunc(kiteProdInstFuncs));
    }

    /**
     * listKiteAttr(获取产品的属性) @Title: listKiteAttr @Description: 根据showType获取产品的属性 @param showType 属性显示控制 D 正常显示的属性，M
     * 更多显示 @param @return 设定文件 @return List<ProdAttr> 返回类型 @throws
     */
    public List<KiteAttr> listKiteAttr(List<KiteAttr> kiteAttrList, String[] showType) {
        return forEach(kiteAttrList, showType);
    }

    private List<KiteAttr> forEach(List<KiteAttr> kiteAttrList, String[] showType) {
        List<KiteAttr> resultAttr = new ArrayList<KiteAttr>();
        if (Objects.isNull(kiteAttrList)) {
            return resultAttr;
        }
        for (KiteAttr kiteAttr : kiteAttrList) {
            if (Arrays.asList(showType).contains(kiteAttr.getShowType())) {
                resultAttr.add(kiteAttr);
            }
        }
        return resultAttr;
    }

    @Override
    public DataResult<List<Map<String, Object>>> listFuncProdInstsByBaseOfferInstYun(String prodInstId, String custId) {

        return ErrorConsts.SUCCESS.getResult(new ArrayList<>());
    }

    /**
     * 点击编辑页面时，将编辑前的属性存起来，点击取消按钮时根据保存的属性还原
     * @param isEdit
     * @param sceneInstId
     * @param prodInstId
     * @param kiteAttrList
     */
    private void saveBeforeEditAttr(String isEdit, String sceneInstId, String prodInstId, List<KiteAttr> kiteAttrList) {
        if (!KiteStringUtils.equals(isEdit, KeyConsts.IFTRUE_T)) {
            return;
        }
        IOperateSceneInstService operateSceneInstService = SpringUtil.getBean(IOperateSceneInstService.class);
        operateSceneInstService.putExtParameter(sceneInstId, prodInstId, kiteAttrList);
    }

    // 处理大带宽自生成端口编号
    private void dealbigBangWidthPort(List<KiteProdInstFunc> prodFuncInstList, List<InstAttrDTO> dtoList, String sceneInstId,KiteProdInstFunc inst) {
        StringBuffer sb=new  StringBuffer();
        sb.append("ORDER00000");
        dtoList.stream().forEach(attr -> {
            if ( KiteStringUtils.isEqual("2_0000223",attr.getFieldName())) {
                if(KiteStringUtils.isEmpty(attr.getValue())){
                    //暂时新增一个序列，有问题待后续完善
                    String SNO = sb.append(SeqUtils.getNext("SEQ_BANG_WIDTH_PROT_ID")).toString();
                    if(SNO.contains("ORDER000001")){
                        SNO = SNO.replace("ORDER000001","ORDER000000");
                    }
                    attr.setValue(SNO);
                    attr.setValueDesc(SNO);
                    operateInstAttrService.setAttrValue(inst, attr.getFieldName(), SNO.toString(), sceneInstId, null);
                }
            }
        });
    }

    //处理物联网通用定制类产品属性处理
    private void dealCommonPlanAttr(List<KiteProdInstFunc> prodInstFuncs, List<KiteAttr> dtoList, String sceneInstId, KiteProdInstFunc inst) {
        if (KiteListUtils.isNotEmpty(prodInstFuncs)) {
            prodInstFuncs.stream().forEach(kiteProdInstFunc -> {
                if (kiteProdInstFunc.getSpecId().equals("300000150")) {
                    List<KiteAttr> kiteAttrList = kiteProdInstFunc.listAttrs();
                    if(KiteListUtils.isNotEmpty(kiteAttrList)){
                        kiteAttrList.stream().forEach(kiteAttr -> {
                            if(KiteStringUtils.isNotEmpty(kiteAttr.getValue())&&kiteAttr.getValue().equals("100006950")){
                                dtoList.stream().forEach(attr -> {
                                    if ( KiteStringUtils.isEqual("200003689",attr.getFieldName())) {
                                        if(!KiteStringUtils.isEmpty(attr.getValue())){
                                            attr.setIsEdit("F");
                                            operateSceneInstService.setAttr(sceneInstId, kiteProdInstFunc.getInstType(), kiteProdInstFunc.getInstId(), attr);
                                        }
                                    }
                                });
                            }
                        });
                    }

                }
            });
        }
    }
    /**
     * Description: <br>
     * 获取功能产品实例属性
     * 安全产品
     *
     */
    @Override
    public DataResult<List<KiteAttr>> listProdInstFuncKiteAttrs(String sceneInstId, String custId, String prodInstId, String isEdit) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInstFunc inst = querySceneInstService.getProdInstFunc(custId, prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();
        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, sceneInst);
        kiteAttrList = this.listKiteAttr(kiteAttrList, new String[] {"M", "D"
        });
        //  kiteAttrList = operateInstAttrService.sortPordInstFuncAttrs(kiteAttrList);
        kiteAttrList = operateInstAttrService.sortProdInstFuncAttrs(kiteAttrList);

       // List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            this.saveBeforeEditAttr(isEdit, sceneInstId, prodInstId, kiteAttrList);
            //dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }
        kiteAttrList.removeIf(attrDto -> KiteStringUtils.equals(attrDto.getShowType(), "E"));
        return ErrorConsts.SUCCESS.getResult(kiteAttrList);
    }
}
